package com.zc.portal.infra.security.metadata;

import com.zc.portal.iface.repository.UrlPattenAttributeRepositroy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.annotation.PostConstruct;
import java.util.*;

@Component(value = "urlInvocationSecurityMetadataSource")
public class UrlInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    private static final Log log = LogFactory.getLog(UrlInvocationSecurityMetadataSource.class);

    private AntPathMatcher antPathMatcher = new AntPathMatcher();
    private Map<String, Set<ConfigAttribute>> roleUrlMap;

    @Autowired
    @Qualifier("urlPattenAttributeRepositroy")
    private UrlPattenAttributeRepositroy urlPattenAttributeRepositroy;

    /**
     * 从数据库加载路由权限角色
     */
    @PostConstruct
    public void loadRolesAndUrls() {
        roleUrlMap = urlPattenAttributeRepositroy.getUrlConfigAttributeMap();
        log.info("初始化路由权限完成！");
    }

    public void reloadRolesAndUrls() {
        if (roleUrlMap != null) {
            roleUrlMap.clear();
        }
        loadRolesAndUrls();
    }


    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {

        if (roleUrlMap == null) {
            throw new IllegalArgumentException("路由权限未初始化！");
        }
        FilterInvocation fi = (FilterInvocation) o;
        String url = fi.getRequestUrl();
        //url匹配 筛选出所有拥有权限的角色
        for (Map.Entry<String, Set<ConfigAttribute>> entry : roleUrlMap.entrySet()) {
            if (antPathMatcher.match(entry.getKey(), url)) {
                return entry.getValue();
            }
        }
        return null;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
